Skip to main content

Full text of "ZXir QLive Alive"

See other formats







pi 






M 


ixxmxl ^vatimx ]$&x 


ti^^xmxxmxx Mszx (Urnups ^sfaskiter 


m 








:!:::j|yi!|3*:(j: i; i!|; 




E I 



(Eljatritratt 



MEMORY MAP 



ADDRESS 



2 
3 



3 
4 
4,5 
5 
6 



8 

12 
15 
16 
16 
19 



20 
24 



ROUTINES 

Information and Chairmen — Trea$ury NoteS 
Input/Output — by Abed Kahale 

QPC — Bob Hartung 

LarKen Boards — Bob Swoger 

Letters - Rod Gowen 

Fire HP 50GC— Bob Swoger 

Sinclair E-Mail List 
From The Chairman's Disk — Donald Lambert 

FILES 

QL Hacker's Journal — Tim Swenson 
ZipaDee BAS — Al Feng 
QLABer Update — Al Feng 
QLATer — Al Feng 

How to Hack on the Spectrum Part 4 — Les Cotrrell 
RMG - Inventory — Jack Boatwright 

SUBROUTINES 



Unclassified Ads 
FWD Computing 




I, m 



1 5 JI 



111 



ill 
It 



hi 
lis 



sy 

■P ill 


















lllliMI 






^..^iM'-:,.:::. 


Illlll 





ii ii 



ZXir QLive Alive! © 
Established 1991 The Timex/Sinclair NorthAmerican User Groups Newsletter 



T/SNUG Information 



We wish to support the following 
platforms: ZX-80/81 , TS-1000, 
Spectrum, TS-2068, Z88 and QL. If 
you have any questions about any of 
these fine Sinclairs, contact the: 

Chairman 

Chief Motivator 
Donald S. Lambert (ISTUG) 

Vice-Chairmen 

Tape & JLO PD Library 
D. G. Smith 
415 Stone St. 
Johnstown, PA 15906 
814 535-6998 

Z88 Library 
Dave Bennett (HATSUG) 
1275 Timber View Dr. 
Mechanicsburg, PA 17055-9146 
717 732-4374 

QL Hacker's Journal 

Timothy Swenson 
38725 Lexington St 
Fremont, C A 94536 
swensontc@geocities. com 

TS-2068 

Rod Humphreys (VSUG) 
10984 Collins PI. 
Delta, BC V4C 7E6 Canada 
604 583-2819 

QL PD Library 

John Donaldson (CATUG) 

835 Foxwood Cir. 
Geneva, IL 60134-1631 
630 232-6147 

AERCO & Z80 Emulator 
Keith Watson 
41634 Amberly Dr. 
Mt. Clemens, MI 48038 

BBS — ==GAT0R=="-- 

Bob Swoger (CATUG) 
613 Parkside Cir. 
Streamwood, IL 60107-1647 
630 837-7957 Work 847 576-8068 

Any of the above can also be 
reached by E-Mail through the 
Club BBS 847 632-5558 



ZXir QLive Alive! 

Is the newsletter of T/SNUG, the 
Timex/Sinclair North American User 
Groups, providing news and 
software support to the T/S com- 
munity in a VOLUME of four 
newsletters per year; beginning with 
the Spring (March) i ssue. 



T/SNUG' s main goal is to 
preserve arid encourage the 
use of Sinclair computers 

by providing an open 
forum for the exchange of 
knowledge, building and 
maintaining of software 
libraries. Providing 
vendors, repair service and 
members with free ad 
space 



It is the user groups and individual 
subscribers, rather than the vendors, 
that provide the pecuniary support 
for this newsletter. Vendors and 
developers receive this newsletter 
free of charge, though contribution 
from vendors and user groups is 
gratefully accepted Please support 
our vendors and service providers 
whenever possible 

If you have a problem or you have 
solved a problem, please share it with 
the rest of us. No problem will be 
considered unimportant . 

' ' ''Publisher ' ■ . 



ou can keep T/SNUG alive by 
an annual contribution of $12 
for one VOLUME made payable to 
Abed Kahale S end check to . - 

ABED KAHALE 
3343 S FLAT ROCK CT 
SIERRA VISTA AZ 85850-6874 
520 378-3424 




I 



Back copies are available for 
$1.00 each postpaid. 

As of August 30, 1998, we have a 
balance of $807.32 



Article 
Contributions 



Send in your articles by tape or disk and your 
inputs to ; — 

DONALD S LAMBERT 
1301 KIBLiNGER PL 
AUBURN IN 46706-3010 
Phone 219 925-1372 
By hardcopy, MSDOS or modem (.3-33 .6) 

to 

Abed Kahale 
E-mail: AKahale@compuserve.com 

3rtot*tet! lair 



To better inform the Sinclair Community, 
four' 24-hour a day BBSs are now provided to serve 
you. You are encouraged to exchange mail and use 
the files sections of these boar ds Bulletins and ads 
are a vailable to all 

Q-BoxBBS 810 254-9878 

Utica, Michigan 
SCC Sever Jose Moreno 
http "//members tripod com/~helpme/ 
SOL BBS 520 882-0388 

Tucson, Arizona 
Club BBS 847 632-5558 
Arlington Heights, Illinois 

If you know the Internet E-Mail address of a 
Sinclair user, but do not have access to Internet, 
simply address your E-Mail to GA TOR Sinclair on 
the 24-hour Club BBS and include the name and E- 
Mail address of the user you wish to reach Then 
check the Club BBS from time to time if you expect 
a reply . 

We encourage you to exchange mail and 
contribute to the UPLOAD section. Call 
and register using your first, last name and phone 
number along with a password you won't forget, 
Write It Down! Do not try to do anything else at 
this time 

When you call-in the next time, you will have 
Level 5 security and be able to enjoy full 
user privileges. The BBS has smaller sections 
called conferences Select "J " for "Join a Confer- 
ence". Select "TIMEX" to get into the Sinclair 
Section. The mail you then read will only be from 
other T/S users. Use extension ART for articles, 
ADS for ads and NWS for news when 
UPLOADing. 

For help, contact the SYSOP, Bob Swoger, by 
leaving a message, mail, E-Mail or phone. 
CENG! 08@email.mot.com 



ZXir QLive Alive! 



2 



Autumn 1998 



Input/Output 



Hello Abed, 

I just received the V8#2 issue. I am still amazed at all 
the info you folks pack into it. I also want to add my email 
address to the list: (panderson2@.home com). It's been a 
while since I had any of my Timex stuff out, but I enjoy 
ZQA tremendously. However, after reading this issue, 
there certainly seems to be a lot of diehards out there 
keeping TS computers alive.. Sinclairly, 

Paul M. A nderson 

Abed. 

I just read Joan Kealy's letter in the ZQA, and I've got 
to say that I agree with her. You really are doing a great job 
for the group I don't know wher_ and the time. 

Speaking of time (saving a little) you don't need to 
reply to this <G> 

P.S I agree with you also - 1 enjoyed those programs (the 
ones that I have seen) that Joan wrote for the 2068 1 even 
tried to get her to write some bagpipe music, but by that 
time she was no longer involved with the 2068. Too bad. 
Take care. 

Dennis Smith 

Dear Abed : 

We have been trying to bring 2068 telecommunicating 
capability "into the third millennium," by updating the 
underlying Z80 CODE to SEND files to modern computers. 
This effort is proceeding slowly. Another, unrelated 
problem causes the "cut off' of connections, while entering 
and/or editing messages. We have traced this phenomenon 
to a lack of free RAM on the part of the 2068, when 
running MaxCom BASIC So, we have reluctantly 
introduced memory-saving techniques, using slower 
instructions. Well, the upshot is, that the computer does not 
operate too much slower, and we want to emphasize a nasty 
little problem, which has been mentioned before in passing. 
In order to save memory, we ordinarily go through the 
code, replacing every occurrence of the numbers 0, 1, and 3 
with NOT PI, SGN PI, and INT PI, respective ' But, 
suppose the code is JJF 0 < x THEN GOTO 5 and v,.e value 
of X is 7. Then, we desire that the instruction take the 
branch to line 5, but the program will fall through to the 
next line, unless we use a couple of parentheses, as in 

IF (NOT PI) < X THEN GOTO 5 
Well, a better solution is to replace such a number 0 with 
CODE "", as in 

IF CODS < X THEN GOTO 5 
Then, we get to use "memory-saving code," without any 
extra parens! 

KeepOnTimex'n 
David E. Lassov: Sysop 

SOL BBS @ 520-882-0388 (data) 

Dear Abed: 

I don't recall seeing that anyone has mentioned the 
scenic photos of Arizona that appear from time to time in 
ZQA! but I, for one, appreciate them. They remind me of 
the times 35 - 40 years ago when I took many of the slides 
in my own collection from that area. 

While looking through my file copy of the listing for 

ZXir QLive Alive! 3 



the BOOT routine that appeared in the Vol. 7 No. 4 ZQA! I 
discovered a typo (mine, not yours) that would halt it with 
an error at line 42. The first variable name should be sic, 
not sis, so the corrected line would be 

42 slceslc-47-39* (slc>57) 
My apologies for the frustrations I caused anyone who 
couldn't get the routine to work. 

Many have expressed concern that Sinclair enthusiasts are 
becoming a passing generation. Not to worry, if a note 
about Marcel Kiigus in the May-June QL Today is any 
indication. It states that he began development of his 
excellent QPC emulator program a few years ago when he 
was 16. 

Near the other end of the age spectrum, an article in 
the same issue by Darren Branagh describes one of the 
recent inventions by Sir Give. It is advertised as the 
world's smallest FM radio It is entirely contained in an ear- 
plug shaped to fit into the ear Tuning is done by touching a 
tiny scanning button 
With best regards, 

Bob Hartu ng _ 

.... When I needed an affordable computer to learn 
programming, the ZX-80 kit was there for $99. No 
more putting up with TimeShare at work.. Abed. 

My guess is that millions of folks were introduced to 
"computers" by Sinclair and Timex I wonder what our 
computer world would be like .... if Timex had continued 
developing and marketing their computer products? Do 
you think we might have a world full of "programmers? 
Today .... folks read thick books and/or go to seminars to 
learn how to use a "given" program on their IBM type 
computers (so the person has to adapt to the computer's 
programs). We adapted the programs (& computer) to our 
individual needs That, to me, was the BIG difference that 
Sir Clive Sinclair brought into being. The Editorial in the 
current Popular Electronics makes reference to the fact that 
many computers in the govt and business areas will have to 

be reprogrammed when the year 2000 emerges and, in 

that, most of programs are in the Fortran or Cobol language 
... it will be necessary to "call" retired programmers (as 
very few of the current programmers know those 
"obsolete" languages). 

If I were one of the "retired" programmer s called I 

believe my asking price would be exorbitant but in that 

I'm not a "retired" Fortran or Cobol programmer ..... I'll 
never have the chance to "gouge" the industries (oh! 
Sadness!). Sincerely, 

Fred Henn 

More NASA Space Images Now Online 
NASA's Observatorium's Gallery expands its collection 
See new photos of the solar- system, Moon, Earth, and more 
at http://observe.iw.nasa.gov/nasa/gallery/image_gallery 
/image_gallery html 

NASA's Observatorium's Gallery, a collection of the best 
in NASA photography and offering full-color, 
downloadable imagery, now has an array of new space 
photos online. 

Autumn 1998 



You'll like what you'll see in the Gallery. From pictures of 
the universe and all its unique inhabitants to exciting NASA 
photography of missions past and present, Gallery gives 
web surfers an up-ciose look at Earth and space science. 

NASA's Observatorium homepage address at 
http://observe.iw.nasa. gov . Contact: 

Scott Gillespie 
NASA's Observatorium 
info@observe iw.nasa.gov 



Frank Davis has LarKen blank boards 
for Disk Operating Systems. He also has 
blank LarKen RAM disk boards, 

— ==GAT0R===~ 



John J. (Jay) Shepard III, wrote: 

Denny, Do not count yourself out till we hear from 
Jack and what the magicians at Computer Classics did with 
his Larken If they turned their magic, do not expect that I 
have it till I check what I rcvd, which I haven't And if I 
have it, do not expect to rev it just by asking for it, till those 
who started this have sorted out all that had been set in 
place, which included Frank Davis and Fwd Computing. 
When all that is resolved you will maintain your position 
behind or beside Jack ; 

J. Shepard 

Thanks for the email about the Larken. I still haven't 
gotten mine back from Computer Classics 1 did receive an 
email from Dan a couple weeks ago stating he was just 
beginning to work on it. I will keep you posted. 
Take care, 

Jack Boatw ri ght 

Hello Abed, 

Well, here it is, the first day of June and I am 
sending you a check in the amount of $49.71. I have 
shipped the last box to Iowa and Jack Boatwright will 
be picking up whatever is left. 

I want to thank you, Bob, and the rest of T/SNUG 
members who donated the funds to get the inventory 
moved. I hope that a lot of it finds new homes with 



someone who can make good use of it 



s 



If I can be of assistance to you or 
anyone else, do not hesitate to ask. j 

,/v v*wv \/wv \/vw v/v^-v s/vw ww s/vw \/v -y\^^/\, 

All of the masters for ant software that I had the 
rights to are now with jack Boatwright. I think that he 
will be willing to distribute whatever folks need or want 
if he has it. Thanks again. Sincerely, 

Rod Gowen 

Hi Abed & Bob, 

I picked up what Rod thinks is the last of the items on 
Friday. Not much really, cables and RF boxes mostly. I 
did purchase another fellow's TS collection that day too. I 
now have quite a lot of TS items, but quite a bit went out 
after the list in ZQAi was published. I hope to have an 
updated list for you in a month or so. 

Take care, Jack 

Dear Al, 

Here is a letter. I sent to Bob Swoger today, 
explaining where I'm at in this project and what kind of 
information is necessary to complete it 



I'm wondering, if you can't read it and maybe also 
have some helpful ideas : 
Dear Bob : 

I have tried several software patches here, trying to 
isolate the difficulty, MaxCom has SENDing files to 
modern computers 

According to the series of decisions, made by the CODE, 
the only thing preventing a normal exit is the receipt of a 
"6" in response to a "4" sent at the end of the last block 
So, would you review what to expect from current 
communications software, at the end of the last block 
SENT? 

The APPLE people are dragging their feet on this 
information, so maybe the Timex people have the answer ! 
KEEP ON TIMEX ,n 
So, Al, what do you think ? 

David Lassov 

Abed, ~ " ~ 

I really need help on this ! 
In Larry's doc on MaxCom, he gives all the control 
characters, SENT by MaxCom to the remote caller. The list 
is about 30 characters long, and he says MaxCom responds 
to A Q, A S, A G, and A \ . . * 

Well, it looks, as though he sends out an EOT ( A D) 
and waits for an incoming ACK ( A F) . The 04 for the EOT 
signals, that no blocks of 128 bytes remain to be sent, and 
the 06 for the ACK is used throughout the CODE, to 
indicate a successful transmission, (then PRINT a '+' !) He 
also PRINTs a upon receipt of a NAK, instead 1 

So, it looks, as though MaxCom responds to 06, or A f, 
or ACK, and 21, or A u, or NAK 

Now, the APPLE uses Proterm communication 
software, and it returns an error after the last block is 
received. It then hangs, and so does the Timex. 

And, the error is "got noise after EOT (1/2688)" 
That 1/2688 is interpreted, as follows "1" stands for "one" 
error, which was detected at byte #2688, which is always "a 
128-byte boundary." 

So, everything seems to be working, OK. Just why doesn't 
Proterm send an ACK, in response to the final EOT ? 
David E. Lassov Sysop, SOL BBS @ 520-882-0388 (data ) 
520-882-3972 (voice) emanon@azstarnet.com (email) 
2590 N. Jordan DR 

Tucson AZ 85745-1132 

Hello Abed, 

Great News!!! I can now READ my own mail 
and other printed material ! 

It has been a long time coming, but I finally had to 
mortgage my soul and pay the price to be able to read 
my own material. 

I am enclosing a photocopy of the spec sheet for 
the machine that I now have working for me. At a 
price of $3700.00 it was not cheap, but it will be all 
mine as soon as I pay the bank off. 

I would like to be put back on the mailing list for 
ZQA! if at all possible. I can now scan it in and hear it 
in a matter of minutes. If I need to send you a 
subscription fee please let me know. 

I hope that we are all straight on the inventory 
that I shipped. I know that Jack Boatwright has been 



ZXir QLive Alive! 



4 



Autumn 1998 




shipping a lot of items out to folks who saw the info in 
ZQA! as well as on the net. If we are not straight on it, 
please let me know 

I will reiterate that I am still available if someone 
needs help in mmh 
any way that H fiS _ fS ,~ _ 
am capable of ^^^^^^^'^^^^^^ 
giving it. 

Thanks 
again for all of ?J*J 
the help and SLs 
your support m 
the past. 

Thanks 
also to all those 
who gave of 
their time and 
money to get the TS inventory moved and distributed. 
Pass them along. Sincerely, 

Rod Gowen 

I'm looking for a working one, pref. with printer + 
modem, but I don't think I can be very choosy at this point. 
;) If you or any of your member's group (TSNUG) have 
any they're willing to part with, please let me know, or let 
them know 7 I'm looking to buy Thanks! 
Louis Florit expressweb.com< 

florit@grep unixville. com 

/ will put an ad in the next newsletter. If you like, 
send me your snail mail address for those who don't 
use email. ^ v Q 1 

Thanks Abed! My snail mail is ZX-51 

Louis Florit 
544.5 SW 150 Place 
Miami, FL 33185 

My pager number is (305)478-3278 

From: Alvin Albiecht <aralbrec@concentric.net> 
Newsgroups: comp.sys. Sinclair Date. Wednesday, July 01, 
1998 Subject: Re: Timex /Sinclair Users groups and 
suppliers 

Michael Owazany wrote; > Anyone know of any 
Timex Users groups in the states these days. Or any one 
who still sells the machines and software 
Yes. Groups: TSNUG: (Timex Sinclair North America User 
Group) Email: AKahale /at/ Compuserve <dot> com LIST 
(Long Island Sinclar Timex Group) Email bmalloy <at> idt 
(dot) net A few others as well You can find the addresses 
in the TSNUG newsletter. 

Vendors: FWD Computing Email: fdavis !at! iquest ?dot? 
net. Also ask at TSNUG as the inventory of another 
vendor, RMG, has been transferred to them Alvin 

Josh Payne 

Joshpayne@bigfoot. com 

Hello Abed, 

I still have a lot of stuff (I bought another collection a 
couple weeks ago from someone Rod knew). 

I still haven't gotten my Larken back from Dan Elliott. 
Sheesh! Oh well, in the latest bunch of stuff I got an Oliger 
with LKDOS, 2 more 2068s, a QL, a 1000 that is really 
loaded and a whole bunch of odds and ends. 



I've been selling the extra stuff from my personal 
collection as well as sending the RMG items for shipping 
costs. Not getting rich, but having a lot of fun and meeting 
new people. 

I hope to have you a revised list of the RMG items 
before the next issue of ZQA! 

Jack Boatwright 

Fife in the Hole 

IIP 500/C printer by Robert Swoger 

Recently my wife's HP 500C printer started to smell bad 
and as it was in a low light area of the room, a small flame 
was visible in the right hand side of the paper tray Shortly 
after that moment, the printer went 'lights out' 

I opened the printer to find that a small drop of ink 
had fallen onto the printer logic board and caused a small 
fire just under the print cartridge parking area. It burned up 
two chip capacitors as well as the PC board under them 

I mentioned the problem at the Glenside Color 
Computer Club meeting and was surprised that a 
few of the \ members present 

knew of the ^ \ ^ — -» problem first hand 

two of llllllllil '"V them had 

the same 
had to buy 
(not HPs). 
told me 




as 

experienced 
problem and 
new printers 
I wish they had 
sooner! 

I found that HP * offers no help in providing 
schematics or technical support for their products. 1 shall 
probably stay away from them next time as they told me to 
forget about trying to fix it and buy a new printer. 

To save the HP printer that you might have, open your 
printer and place a plastic or cardboard ink shield over the 
PC board just under the area where the print cartridge 
travels, especially under the print cartridge parking area 
This area is readily seen by looking for the two banks of 
four diodes in the right top corner of the PC board 

Fix it BEFORE it happens to you and - GOOD 
LUCK! — ==GATOR== — 





Albrecht, Alvin 


aralbrec@concentric. net 


Anderson, Paul 


panderson2@home. com 


Anson, Gerald 


jerrya@aztec.asu.edu 


Barker Robin 


Robin@di-ren. demon, co.uk 


Bennett. Dave 


dbennett@.epix. net 


Boatwright, Jack 


jboatno4@outlawnet. com 


Boehm, Al 


boehm@ziplink.net 


Boehm, Bill 


boehm@plh.af.mil 


C. A. T. S. 


mf0002@epfl2.epflbalto.org 


Cable, Bill 


bcable@triton. coat, com 


Chambers, George 


gfchamb@pathcom. com 


Collins, Bill 


bcollins@home.ifx.net 


Cottrell, Les 


jacottre@gte.net 


Cruz-Figueroa, Jaime 


cruzfiguer@aol.com 


Dansby, Andrew 


adansby@atlantic.net 


Davis, Frank 


fdavis@iquest.net 


England, William 


wengland@iname.com 



ZXir QLive Alive! 



Autumn 1998 



Fens, Al 


alfeng@juno . com 


Florit, Louis 


florit@grep.unixville. com 


Fink, Mike 


domino . cubes@excelsior . net 


Franke, John 


j.m.franke( 


^larc.nasa.gov 


Ganger, Gary 


gangerg@dma. org 


Gillespie, Doug 


aa43 l@cleveland.freenet.edu 


Harbit, Ken 


krh03 @csufresno . edu 


Henderlight, Mike 


mikehend(a),microsoft. com 

' — j 


Henn, Fred 


oranur@ju 


no.com 


Hunkins, James 


j dhunki@ibm. net 


Imrjellizerri, John 


jimpellizerri@compuserve.com 


Jaap, Matthias 


Matthias Jaap@hhs.hh.schule.de 


Jonas, Mike 


mjonas@bbn.com 


Jones, Terry 


tjones@iname. com 


Kaczor, Jon 


75363. 1 127@compuserve.com 


Kahale, Abed 


akahale@compuserve. com 


Kealy, Harriet Joan 


hjkealy@ms 1 .hilconet.com 


Kinssley, Ed 


elk4@aol. com 


Konm, Urs 


urs koenis^aarodata ch 


KurtK7 


kurtk7@aol . com 


Kwitkowski, Phillip 


kwit47@ao 1 . com 


Lancaster, Garry 


dharkhisfS)derDhi com 

Ik*. I lLlll ^M^V# Vi.^/ X. 1. 1 , V* * Jill 


Lassov, David 


emanon@azstarnet . com 


Lebowitz, Dave 


dkl@dpliv.com 


Lessenberry, Gary 


glessenb@usr.com 


Liebert-Adelt, Peter 


p.liebert@t-online.de 


Malloy, Bob 


74776.1 161@compuserve.com 


MeKelvey, William 


mckelveyw@delphi.com 


Merz, Jochen 


jochenmerz@j-m-s.com 


Miller, Seymour 


sey mil@delphi . com 


Muth, Bob 


bobkeeperl@aol.com 


Norton, Gary 


gnorton@world.std.com 


Parrish, Gil 


1 07765 .1161 @compuserve. com 


Pashtoon, Nazir 


napware@ 


juno.com 


Pazmino, John 


john.pazmino@moondog. com 


Perry, Russ Jr 


slapdash@enteract. com 


Rigter, Wilf 


rigter@cafe.net 


Rish John 


7460 1.153 5@compuserve. com 


Shepard, Jay 


j shepard@netins. net 


Simon, Thomas 


73177.333 


^Compuserve, com 


Skapinski, Tom 


tskapins@ : 


uno.com 


Smith, Dennis 


denny.smit 


h@juno.com 


Swenson, Tim 


swensontc( 


^geocities.com 


Swenson, Tim 


swensont@sirclive.csd.sgi . com 


Swentko, Wally 


wswentko@maroon.tc.umn.edu 


Swoger, Robert 


ceng 1 08@email.mot. com 


Taylor, Jeff 


jetaylor@spar.ca 


Thoresen, JefF 


74200.257@compuseive.com 


Walterman, Don 


walterm@ix. netcom. com 


Washington, Barry 


mf0002@epfl2.epflbalto.org 




B 

rap WjW 


cn 

1 p Gil Parrish 



Perhaps someone can help me with identification of a 
TV/monitor interface that appears to be ZX/TS related.. The 
story goes that I was in a thrift store and found a PC8300. 
If you don't know, a PC8300 is a Hong Kong "clone" of a 



ZX-81 or TS1000, with many similarities (like an identical 
expansion edge card), but also with some different and 
additional features (I did a piece on writing music for one 
in the Summer '95 issue of ZXir QLive Alive!). Anyway, 
sometime later I was in a different part of the same store 
and ran across the video interface in question, so that 
interface may or may not have anything to do with the 
PC8300. 

It has a non-shiny creme plastic case (the PC8300 has 
a shiny creme case) with four diagonal stripes on the front, 
being (top to bottom) red, blue, yellow and green. (The 
PC8300 is marked with green of about the same shade, but 
none of the other colors ) It has a ZX/TS-style expansion 
connector with passthrough edge card, and a short (maybe 6 
to 7 inch) hard-wired cable on the right side (as you would 
view it from the computer keyboard) with an RCA plug at 
the end. On the left side, it has two RCA jacks, labeled 
"TV" and "Monitor", and (if you open the case) the TV one 
is connected to an RF modulator box not unlike what you 
find on a ZX/TS motherboard. There is no marking on the 
outside of the case, and about the only marking on the 
board inside is "LAMBDA". 

Now, my first guess was that this added a monitor port 
to the PC8.300 by attaching to the TV output. But then I 
remembered, the PC8300 already HAS a monitor port, as 
well as a TV port (Channel 3). I then thought maybe it was 
intended to add a monitor port to the ZX/TS. But the 
expansion edge card on a ZX/TS is (as you face the 
keyboard) to the far right, so that right-hand cable on the 
interface couldn't attach to anything (The TS2068, by the 
way, also has its expansion edge card at the far right, and 
also already has both a TV and a monitor port While the 
TS2068 does have three short stripes on its primarily-silver 
case in the colors of red, green and blue, it has nothing in 
creme or yellow ) The PC8300 has its expansion edge card 
in the middle, with the monitor port to the right and the TV 
port to the left, so the interface could fit that edge card and 
have its RCA plug in the monitor port. But again, why? 
The PC8300 already has a TV and monitor port. 

Despite the lack of sense, I tried attaching the 
interface to the expansion and monitor ports of the PC8300. 
My monitor (hooked to the monitor output jack of the 
interface with an RCA-to-RCA cable) showed something 
that might have been a normal picture, only with vertical 
and/or horizontal hold totally misadjusted. No amount of 
adjustment brought the picture in. On the TV, I got nothing 
until I hit UHF channel 35, and then I got the same kind of 
twisted, unadjustable picture I got on the monitor. 

I can speculate a lot here The device could be some 
kind of faux-color adapter (hence the stripes), but this 
particular interface is defective. Or maybe it was intended 
for the European Spectrum or other r elated model (how 
would I know, when I've never even seen a Spectrum in 
person?) and won't work on North American systems. Or 
possibly it was intended to modify the PC8300 to European 
(PAL or SECAM) use Or perhaps I'm simply missing the 
point as to its purpose or usage on the PC8300 Anyway, if 
someone knows, drop me an e-mail at 

107765.1 161@compuserve.com 
and take me out of my puzzlement. 

My wild guess is thai it was made for viewing the 
Spectrum on US video monitors. Editor 



ZXir QLive Alive! 



6 



Autumn 1998 



Donald S. Lambert 




[hat a summer! Hot or hotter than usual and then a 
Wry spell for a while and then too much rain for 
some areas. Living in Auburn, IN gives us some protection 
from the storms since we are the right distance and 
direction fr om Lake Michigan to be in the area too far from 
the storms that the lake generate and too near from the lake 
for the other storms to really affect us with the extreme rain 
(or snow) fall that others get. And since all our power 
comes in from other areas we do get an occasional power 
losses mostly caused by excessive loads during the really 
hot weather That really affects those that have a sump 
pump . We don't have a basement so no worry about that, 
ijtffasakos my wife was watching TV one day and she 
2'*** tried to change from her soap to QVC (a shopping 
station on cable) by way of the FLASH button and it didn't 
change stations. She tried the up and Down button and 
while the screen flashed as it did for the FLASH button it 
didn't change stations. So of course I was called to the 
rescue and I checked the other TV and it worked properly 
so I made an immediate conclusion that the AAA batteries 
in the remote were weak. However ! with the original 
batteries it would get the proper station if you punched in 
the station number I tried another set of batteries and still 
the same and I tested the batteries and still good so now 
what? Either the TV or the remote was bad. I took the 
remote and went to the local store where we bought the TV 
and the remote tested good (it put out an infrared beam) and 
a set of the same make (Zenith) was on in the display so I 
found that remote was working for sure. 
'Tir'he service man suggested that maybe the power outage 
^fcl/had done it Why wouldn't it show up right after the 
outage? So back home I read the manual and did a from 
scratch start up. Which was to have the TV find out which 
channels had a program While I was at it I reset the clock 
that showed on the screen when you changed stations 
After that the remote operated correctly Nowhere in the 
manual does it mention what to do in case of a power down 
situation. In my eyes that TV had a case of loss of short 
time memory or a case of Alzheimer's disease. What 
connection to the T/S computers, Just pointing out there is 
so much that isn't manuals covered in the manuals 

Che May issue of NUTS and VOLTS magazine in Tech 
Forumn department of the magazine was the request 
for informatiom. I have an old Z88 made in Scotland that 
works. It has new AA batteries "How do I connect it to my 
IBM 486 or my PowerMac 7200?, and with what cables in 
order to download notes of ASCII type. Do I need software 
and where can I get it? David McGuire." I sent in 
information about the cables and software that Frank Davis 
had for sale and NUTS and VOLTS magazine printed my 
reply in the June issue. They stated that the first reply 
printed in the answer column of that department would get 
a check of $25. My wife laughed "oh yeah!" The check 
arrived on August 15th. Now what will I buy with it? 

[hen I checked the price of dishwashers at Sears I 
Wrifted over to the computer section TV/Internet 
deal. A poor man's way of going on line This one had a 
printer port and a hard drive but no floppy drive Complete 



with printers keyboard and interface it ran about $400 new 
and only required to pay the $20 monthly fee to go on line 
I was thinking of hooking one up to my AMDEK COLOR-I 
monitor of which I have two. But then I remembered that I 
could probably buy an IBM compatible used computer for 
less than that and have the ability to do so much more But 
then I would have to relearn how to use a computer And 1 
still have the Z88 to Conquer. I have lived this long without 
being on line so I can live some more 
I do have a Z88 and a modem for the Z88 so I could go that 
route to go on line. BUT! just how does one do it? 

Can someone give me a step by step 
guide as to how to do it? 

Txternal battery case for the Z88 — I wanted to have a 
'way to keep a Z88 alive for extended periods of time 
and the internal AA batteries don't last long By that I mean 
if the Z88 is in a hanging file folder for half a year at a time. 
I could use alkaline batteries but then they do expire given 
enough time. I thought of rechargeable batteries the first 
choice is NIC AD BUT! the NIC AD have a tendency to 
discharge while sitting on the shelf The literature states that 
a NIC AD will self discharge in about a month So they are 
out But I have had good results with RAYOVAC 
RENEWALS in the three quartz clocks we have. They each 
use one AA battery and I swap them out and recharge them 
periodically and have for several years. 

.o I collected the necessary parts and the ! D' sized 
batteries I managed to find the batteries on sale so that 
helped so were the coupons that I redeemed to even get 
more discount I have 6 batteries in series to power the Z88. 
O K. I know that the total theoretical voltage of 6 batteries 
is 9.9 volts. So I put seven 1N4007 diodes (why 1N4007 
diodes that was what was in the diode bulk package at 
Radio Shack) in series with the power and have a DIP 
switch acr oss each so that I can short out the diode if want a 
higher voltage I also found out that with no load on the 
circuit that I get a higher voltage than what I expected I did 
not charge the batteries before I tested the battery box that 
built. The batteries in series give 9 42 volts. I tested the 
computer in the sleep mode (turned off) and with it 
powered up I used a digital multimeter. The following 



No Load 6.S4 


No Load 7.28 


No Load 7.29 


Sleep 3 54 


Sleep 5 82 


Sleep 5.95 


Z88 ON 


Z88 ON 3.98 


Z88 ON 3.9.5 


Doesn't Power Up 


Gives BAT low 


Gives BAT low 


No Load 7.82 


No Load 7.97 


No Load 8.31 


Sleep 634 


Sleep 7.08 


Sleep 7.56 


Z88 ON 4 87 


Z88 ON 5.63 


Z88 ON 6 30 


Gives BAT low 


Gives BAT low 


Full operation 




{^recording to some literature that I received from 
iCiRAYOVAC the RENEWAL batteries give more 
recharge cycles if they aren't discharged too deeply One 
place mentions that they shouldn't be discharged below 13 
volts or a total of (6 X 1.3) 7.8 volts. I will try to aim for a 
total of 8.4 or 14 per battery to be sure. Even so they 
should give a long life compared to AA batteries. 0/0 



ZXir QLive Alive! 



7 



Autumn 1998 



QL Hacker's Journal 



#2S July 1398 

The QL Hacker's Journal (QHJ) is published by Tim 
Swenson as a service to the QL Community The QHJ is 
freelv distributable. Past issues are available on disk, via e- 
mail, or via the Anon-FTP server, garbo.uwasa.fi The QHJ 
is always on the look out for article submissions. 

QL Hacker's Journal 

c/o Tim Swenson 
24.55 Medallion Dr. 
Union City, CA 94587 
swensontc@geocities. com 
http://www geocities com/SilconValley/Pines/5865/ 
Note New Mailing Address 

Editors' Forum 

have not received much feedback on the QLiberator 
Source Book idea I mentioned in the last issue, and I 
have received basically no "helpful hints" So, my plan is 
to write what I can, put it out on the Net, and see what 
feedback comes from it If I make any mistakes, I'm sure 
there are many willing to point out my failings .-). 
Sometimes the best way to get an answer to a question is to 
give a wrong answer, then many will pop up to give the real 
answer. I'll probably put in questions that I have in the 
hope that they too will get answered. 

Apart of the material going into the Source Book is 
coming from stuff I'm writing for this newsletter. I 
have taken the article on adding Config Blocks to QLib 
program and expanded it quite a bit. A couple of articles 
from this issue will also go in. I also plan to have sections 
that touch on the various SuperBasic extensions and 
programming aids available to the SuperBasic 
programmers. 

In other news, besides having past issues of the QHJ 
available on my web page, I've added a number of 
articles that I've written for other newsletters. Check the 
link from the main page 

Structured SuperBasic 2.6 

Structured SuperBasic is a utility that has been printed a 
couple of times in this newsletter. I have recently 
dusted the program off and completed a new version. SSB 
2.6 has ail of the functionality of SSB 2.5, but I have added 
a lot of error checking, fixed a few bugs, added Config 
Block support, Command Line support. Environment 
Variable support, and compiled it with QLiberator. The 
manual has been expanded from 5 pages to 16 pages. The 
whole package has been zipped and should be available 
your local QL BBS and the Internet. It can be downloaded 
off my web page at http://www.geocities.com/Silicon 
Valley/Pines/5865/. 

For those that don't remember what SSB is, it is a filter 
program that takes SuperBasic code, written in the form 
for SSB and converts it to full SuperBasic code. SSB 
allows for no line numbers, blank lines between code 
segments, conditional compilation, Include files, and other 
features. SSB allows for more readable and maintainable 
code. Download the package, unzip it, and give it a try. 



Revision Control System (RCS) 
hether it's source code or system configuration files, 
it's nice to be able to keep track of changes made to 
files over time The Revision Control System is a 
collection of programs that keep track of different versions 
(revisions) of text files. A special file is created by RCS 
that contains information about the changes in a file and 
allow the user to get back to any revision of the file . 
RCS was designed primarily for programmers to keep track 
of what changes were made to various source files. It was 
derived from an earlier Source Code Control System 
(SCCS) and was first developed for the UNIX operating 
system. 

Since RCS came from a UNIX background, it 
understands the concepts of different users accessing 
the same files and allows "checking out" files and locking 
them from being changed by other users. RCS can be used 
by a number of programmers all working on the same code 
It keeps track of who has what file "checked out" and who 
makes what changes. 

Jfk Ithough most QL programmers program by 
#%themselves, RCS can help the QL programmer bring a 
form of discipline to their programming This is especially 
useful for what can be called "full production" programs, 
commercial or Freeware. Given the long life of QL 
programs (I'm still using programs written more than 10 
years ago), RCS can keep track of what changes were made 
from revision to revision and why A programmer can keep 
make a rule that each RCS revision be a bug fix and the 
reasons for the fix can be logged as part of the revision 
history. 

Enough blathering on, now to jump right into what RCS is 
and how it works. 

Original File - This is the text or source code file that 
you want to keep track of It can be any text file. 

Revision File - This is a single file that contains the 
original text/source file and all of the revision history. It 
has the same name as the original file except that a ',v' is 
appended to the end. if the original file is test_c', then the 
revision file is called 'test_c,v' A revision file keeps track 
of only one original test/source file If you have 3 source 
code files that make up a single executable, then RCS will 
have three revision fills. 

Check-In - All revisions to a file are put into the 
revision file by checking them in The program 'ci' is used 
to do this, 'ci' is used to either create a new revision file or 
to check-in a new revision into an existing revision file. 
Once a file has been checked into the revision file, it is 
deleted. 

Check-Out - When you want to edit a text/source file 
that has been checked in to the revision file, you use 'co' 
(check-out) to extract the text/source file from the revision 
file. 

The whole process of using RCS is basically checking-in 
and checking-out the same file. RCS is not aware of 
time, so there is no need to check-in a text file when you 
have finished a programming session. You really only need 




ZXir QLive Alive! 



8 



Autumn 1998 



to check-in a file when you have made all of the edits you 
need. If you are fixing a bug in a program, you would only 
check-in the file when you have fixed it. No need to keep 
track of working copies of the tiles. 

To show you how RCS is used, I've written a short 
Structured SuperBasic program. 

OPEN #3, con lOOxlOOalOOxlOO 

CLS #3 

INPUT "Enter The Name of a File 
: "; file$ 

0PEN_IN #4, f ile$ 
REPeat loop 

INPUT #4,in$ 

IF EOF (#4) THEN EXIT loop 

PRINT #3,in$ 
END REPeat loop 
CLOSE #4 
CLOSE #3 

I stored this program in the file 'readfile_ssb' I then 
checked it in to RCS using the following command; 
exec ci; "readfile ssb" 

'ci' then asks me for my initials. Since the QL does 
not have the concept of multiple users (and therefore user- 
names), a persons initials are used to keep track of who 
has checked out a file and who has made what changes to 
that file 'ci' then asks for a Description The Description 
is where the "why" of the file change is kept track of. If 
you are using RCS to keep track of bug fixes for a 
program, the Description section would be used to mention 
the bug, what caused it, and how it was fixed I do not 
believe there is a limit on how long the description can be. 
The Description is ended by a line with just a period on it. 
'readfile__ssb' is now checked-in to the RCS revision tile 
and is deleted. 




ow to get the file back to edit it, I ran the following 
command: 



exec co;"-l readfile_ssb" 
I need to tell 'co' what file I want, but I also have to 
tell 'co' that I want to edit the file If I ran 'co' without the 

option, 'readfile ssb' would have been created, but it 
would not have been "checked-out" from the revision file, 
and when I went to check it in, RCS would not have 
allowed it. Under UNIX, 'co' would create a 'read-only' 
copy of the file, 'co' asked for my initials. 

Since the same person who checks out a file is the 
only person the can check in a file, be sure to remember 
what initials you used. 

! readf!le_ssb' is now extracted from the RCS file 
and the revision file is changed to show that the file is 
checked out. 

Once I am done editing the file, I can then check in 
the file using 'ci' Again I am asked for my initials. The 
file is now checked back into the revision file and deleted. 
If you copied the file before checking it back in and you 
have edited this file, you can not incorporate those changes 
into the revision file since the file is 'officially' checked in 
and can not be edited. 

CS uses revision numbers to keep track of the 
different times a file is checked-in The first revision 
is 1 1, then 1.2, then 1.3 and so on. Let's say that I have 
edited my file 4 times, I'm now at revision 1 5 and want to 
recall revision 1.3. I would run the following command; 



exec co,"-r 13 readfile_ssb" 

'co' would then dig though the revision history and 
generate version 1.3 of 'readfile_ssb\ 
■"ICS comes with more than just the 'ci' and 'co' 
Smprograms. 'rcsdiff is used to compare a working 
"checked-out" file with the version still in the revision file. 
Ylog' is used to view the revision file. 
Below is the output of 'rlog' from my example session: 

RCS file, readfile _ssb,v 

Working file: readfile_ssb 

head: 1.2 

branch: 

locks' strict 

access list: 

symbolic names 

comment leader: "# " 

keyword substitution: kv 

total revisions: 2, selected revisions: 2 

description; 

Creation of RCS Archive 



revision 1.2 date- 1998/06/11 20:41:01; author; tcs, state: 
Exp; lines: +2 ~2 

This is a second version of this program. 



revision 1.1 date: 1998/06/11 20:19:34, author: tcs; state: 
Exp, Initial revision 

RCS is a lot more complicated that I've mentioned here. It, 
and SCCS, is fully documented in the book "Applying 
RCS and SCCS" by Bolinger & Bronson, published by 
O'Reilly & Associates RCS for the QL is available from 
most Freeware sources The QL RCS distribution does 
not come with the 'diff program which it requires. 'difF 
is available as part of the C68 distribution. 

RCS can not be used with regular SuperBasic 
programming, as RCS would see any new line 
numbers as a change in the file If you loaded a file into 
SuperBasic, did only a line renumber, saved it, and then 
check it back into RCS, RCS would any line with new line 
number as having changed. RCS works well with 
Structured SuperBasic as it has no line numbers. It also 
works well with C, Forth, Pascal, etc. 

Environment Variables 

The concept of Environment Variables comes from the 
Unix world They are used slightly in MS-DOS, but 
not at all to the same extent as UNIX. For the QDOS 
world, the file ENVJBIN provides a number of extensions 
that allow the use of Environment Variables. Essentially an 
environment variable is a variable that can be "seen" by 
executable programs. In SuperBasic we can set up all 
kinds of variables, but if we execute a program from 
SuperBasic, these programs can not "see" these variables 
and get data from them. 

The puipose of environment variables is to 
change the configuration of a program. They function 
like Config Blocks, but don't require running a program to 
make the change Let's take a quick look at how we can 
change the behavior of programs There are five different 
ways of doing this: 

1) User Intervention. This is where the user uses a 
menu or answers quer ies from the program. 

2) Config Blocks. This feature is pretty unique to 




ZXir QLive Alive! 



9 



Autumn 1998 



QDOS, but it allows the user to change default options 
without having to know how to edit a binary file. 

3) Configuration File. This is a separate file that the 
program reads to determine how to set defaults and run. 

4) Command line Arguments. Instead of the program 
querying the user for infor mation, the user types it in when 
they execute the program. 

5) Environment Variables. The user sets a variable that 
is then read by the program and changes its default settings. 
Each of the options have their own place and their own 
benefits and faults. Some are more permanent, like 
Config Blocks and Config files, while some are very 
short lived, like User Intervention and Command line 
Arguments. Environment Variables are in between as they 
can be set in a BOOT program, but they can be changed by 
just typing in a new command 

The ENVJBIN file comes with 4 extensions. They are: 
SETENV - Defines an environment variable. 
ENV LIST - Lists all defined environment variables. 
ENVJDEL - Deletes an environment variable. 
GETENVS - Gets the value of an environment variable 
The two key commands are SETENV and GETENVS. 
SETENV is used like this. 

SETENV "VARIABLE-value" 
SETENV takes a string argument of the type 
"XXXXX=YYYYY M where XXXXX and YYYYY are 
two strings separated by an equal sign. Any space before 
the equal sign is treated as a part of XXXXX and any space 
after the equal sign is treated as a part of YYYYY. The 
case of each string is important as "VARIABLE" is 
different from "variable". By convention, upper case is 
used for variables . 

The SETENV is done either in a BOOT or setup 
program or by the user The command for an 
executable to get the contents of an environment variable 
is GETENVS. The command is used like this: 
a$ = GETENV$(" VARIABLE") 
In this case a$ will be assigned the value of "value". 
This comes from our previous SETENV'' command above. 
If the Environment Variable "VARIABLE" is not set (does 
not exist) then the GETENVS would return a Null string ( 

Now I did say that executables use GETENVS and 
not SuperBasic programs. Since variables are 
already used in SuperBasic, we would not gain much in 
using environment variables. There the commands are use 
is in compiled SuperBasic programs, which are 
executables. 

I see the purpose of using Environment Variables as 
adding to the flexibility of programs that use Config 
Blocks. Both Config Blocks and Environment Variables 
are really designed to change default program settings 
User Intervention and Command Line Arguments are 
designed to tell the program what the data is. Using 
environment variables allows the user the ability of making 
a temporary change to the default options of a program, 
without having to go through the trouble of using "config" 
Environment variables would be used to change a setting 
for a single session and that's it. 

Getting Config Blocks and Environment Variables to 
work together is not difficult. The program would 
first get it's default settings from the Config Block. It 



would then check to see if there are any Environment 
Variables set. If there are, then the Environment Variable 
settings would override the Config Block settings. 
Working Directory 

As we all know, QDOS did not come with the concept of 
directories and subdirectories. A number of extensions 
to QDOS are available to help create the working concepts 
of directories When using ED drives, I found the Path 
(PTH) extensions useful because they would search a list 
of subdirectories looking for a particular executable 

Now, I've never used a QL with a hard disk, so I'm 
not too experienced with using the tools for handling 
directories, plus my copies of some of the good articles 
dealing with this subject are not available to me. So, I've 
been doing some thinking on the matter, especially since I 
have been writing a Freeware program and I want to 
make it as versatile as possible. 

The one issue that I've been pondering over is telling a 
program where there data file are at This is 
called a Working Directory. It is a directory where the 
data files are at and any newly created files will also go 

I know that DATA USE is designed for this purpose, 
but I do not want to type in a new DATA USE before each 
program I execute I could set up a short little 
SuperBasic program to set up everything, but I want to 
EXEC a program not LRUN it Of course, using a front 
end like QASCADE, this point is mute, since the user is 
removed from the details of executing the program. With 
PTH setup, 1 don't need to set PROG USE, because 
PTH_ finds the executable 1 was looking a way of having 
the executable know where the Working Directory is 

What I came up with is this. Have an item in the 
Config Block for Working Directory. The contents 
would be something like this, "WIN 1 PROG DATA " 
This string would be appended to the front of each file 
name used in the program. This does mean that the user 
would not be able to type in a new device name, such as 
H FLP 1 FILEEXT" . Initially, the Config Block entry for 
Working Directory would be the null string (empty), so 
that a user would' enter "FLP1 FILE EXT" Once the 
user has created a working environment, the Config 
Block can be changed to what the user wants. 

if this feature is linked to Environment Variables, it 
would become more powerful By setting an 
Environment Variable for the program, the user could 
temporarily override the Config Block and change the 
Working Directory. If the Config Block was changed to 
a Working Directory and the user needed to use the 
floppy for a few times, the user would set the 
Environment Variable to "fipl _" or to the null string ("") 
and then set DATAJJSE to lpl_ If they did not want 
to change the default Config Block, a BOOT program 
could set the Environment Variable and it would be active 
during the whole computing session. If different programs 
used different Environment Variable names for their 
Working Directory, then all Working Dir ectories could be 
set up in the BOOT program Something that could 
not be accomplished with just DATA_USE 

Since my experience in this area is kind of light, the 
more experienced QLers may want to take this all with 
a grain of salt I prefer to think of it as a way that I would 
prefer to organize things and others may have a different 



ZXir QLive Alive! 



10 



Autumn 1998 



way. 

The reason I am bringing up this idea is for 
programmers to consider the concept and add it to 
their programs. The option is not very difficult to 
implement, but it would a nice feature to the program 
The whole feature would take up no more than 10-20 extra 
lines of code to a program. By setting the default value of 
Working Directory to nothing, the feature is essentially 
turned off and it does not impede the user that does not 
want use a Working Directory 

Case Statement Implementation 

When I recently was working on S SB 2.6, 1 was using 
a SuperBasic implementation of a CASE structure 
for the core of the program The deeper the structure got, 
the harder it was to read and understand. I starting 
thinking of using another way of implementing a CASE 
structure. 

For those that don't know what a CASE structure or 
statement is, it is essentially the same structure as a 
SuperBasic SELECT ON statement, but it is not limited to 
numbers. Plus the general idea of a CASE structure is to 
have a number of possible logic statements with an action 
for all cases that do not fit one of the logic statements In 
a generalized CASE structure not all of the comparisons 
must be based on the same data (string, number, etc), but 
can vary. 

Traditionally, a way of creating the CASE structure is 
to have a number of nested IF.. THEN ELSE 
statements, with the final ELSE handling the default value. 
An example would be something like this: you are reading 
in text from a file. You want to handle the following 
cases: a line starts with a ##, or a line starts with a **, a 
line starts with a period (.). If none of these cases, then 
the line is passed to the output file 

Using nested IF THEN. .ELSE statements the pseudo 
code would look something like this: 
IF line starts with ## THEN 
ELSE 

IF line starts with ** THEN 
ELSE 

IF line starts with a period THEN 
ELSE 

pass to output file 
END IF 
END IF 
END IF 

If you start having more than just a hand full of possible 
cases, the structure can get long and difficult to read. 

SuperBasic allows the use of NEXT in conjunction 
with a REPEAT statement. This means that when the 
NEXT is reached, the rest of the REPEAT loop is skipped 
and the processing goes onto the next interaction of the 
REPEAT loop. Using NEXT in this manner allows for the 
creation of a different implementation of a CASE 
structure. Below is an example of the two implementations 
listed side-by-side. 

REPeat loop REPeat loop 
IF THEN IF THEN 



ELSE 

IF.... THEN 



NEXT loop 
END IF 
IF.. THEN 



ELSE 

IF .... THEN NEXT loop 

END IF 
ELSE IF ... THEN 

default 

END IF NEXT loop 

END IF END IF 

END IF default 
END REPeat loop END REPeat loop 

Using the REPEAT .NEXT END version may not 
seem as clean as the "classical" IF. THEN.. ELSE 
structure, but I think it is cleaner when it come to reading 
and debugging What I am looking for from readers is to 
ponder over any downsides from using the 
REPEAT. NEXT structure I can't think of any logical 
problems with using this structure over the classical one. If 
you know of any, please send me a note. I'll add the 
productive comments in the next issue. 

Creating Loadable Extensions Using QLIB 
#%ne of the things that has always amazed me about the 
%&QL was the ability to load a binary file and have a 
bunch of new keyboards available in SuperBasic In most 
computers that had Basic built in, the language was static 
and had no way to extend itself. Other languages (like C, 
Fortran, or Pascal) used libraries of functions and 
procedures to extend the capability of the library. 
The first major LOADABLE extenuation to the QL was 
ToolKit. From then on the term toolkit has been used in 
reference to LOADABLE extensions. Popular toolkits are 
ToolKitll (TKII), DIY ToolKit, and DJToolKit. 

I knew that the first of these toolkits were written in 
Assembly, but I did not know that they could be created by 
QLiberator It seems that QDOS executables and 
extensions are real close in format and when compiled 
right, they can be interchangeable. This means that an 
executable can also be loaded as an extension. To figure 
out how to create a toolkit, I grabbed a simple 
function, QLiberator, and gave it a try. The function is 
included below: 
10 REMark $$ external 
100 DEFine FuNction upper$(up$) 
110 LOCal x, temp 
120 FOR x = 1 TO LEN(up$) 
130 temp = CODE (up$ (x) ) 

140 IF temp > 96 AND temp < 123 THEN 

up $ ( x } =CHR$ ( t emp- 3 2 ) 

150 NEXT x 
160 RETurn up$ 
17 0 END DEFine 

The function takes any string and converts it to all 
upper case letters, The $$exteraal is a compiler 
directive to QLiberator that tells it that the next function 
or procedure needs to be available outside of the 
executable. For each procedure or function that you 
want to turn into an extension, you would have to put the 
$$exteraal directive in front of it If I was to put an 
additional line in the program, 

180 PRINT upper$ ( "This is a test") 
then when I executed the program, line 180 would be 
executed. If I LRESPRed the program, the keyword 
upper$ would be made available. 



ZXir QLive Alive! 



11 



Autumn 1998 



When compiling the program it is a good idea to turn 
WINDS off, since the extension will have no 
channels open. Otherwise 3 channels will be opened for 
it, wasting them To lower the size of the binary file, 
turning off NAMES and LINES might be a good idea. 
Note that the case of the function or procedure will be 
maintained in the extension. In my example, the name 
that will show up when entering EXTRAS is "upperS" (all 
lower case). If I defined the function a UPPERS, then 
"UPPERS" would show up in the EXTRAS command. By 
convention, extensions should be done in all upper case. 
1 f you will be running the extension on a system that 
1 already has the QLib runtimes loaded, then compile 
the program without runtimes. If you don't know if the 
QLib runtimes will be available, compile it with the 



runtimes included. It is a good idea to compile both ways 
and let the user decide which one they need. The example 
program when compiled without the QLib runtimes was 
594 bytes. With the QLib runtimes it was 11,146 bytes. 
The runtimes take up a fair bit of space. 

If you load an extension that does not have the QLib 
runtimes on a system where the QLib runtimes are not 
loaded, you will not get an error message when you 
LRESPR the extension. When you call the extension is 
when the error will occur The exact error message is: 
Error "Runtimes Missing !" 

Once you have compiled an extension, all that is 
needed is to LREPSR it and test it out. Remember 
that you can't LRESPR while any jobs, other than Job 0 
(SuperBasic), is running. 



ZipaDee Bas 1.105 



by Al Feng 



Several years ago, Anthony Trice was kind enough to 
send me a copy of the ZIP utility which was originally 
ported to QDOS by Erik Slagter & Kai Uwe Rommel. 
Unfortunately, need is a strong motivator, and it wasn't until 
this Summer that I finally sat down to figure out how to 
implement the utility in its QDOS incarnation ZuipaDee 
(1 . 105) is the long over due front end for the ZIP utility that 
is meant to complement the earlier DooDah bas front end 
for UNZIP,, 

While more than one compression algorithm exists, 
the use of the earlier 'LZ77' algorithm allows a QDOS 
ZIPped file to be universally expanded by almost all 
versions of UNZIP , The most recent port of ZIP that I have 
(v3.0) was executed by Marco Holmer. 

Using Zip 

There are many reasons for ZIPping a file - the two 
reasons that come to mind are for archiving (storage) and 
transmission (distribution) Of cour se, the file or program 
cannot be used until it has been UNZlPped back to its 
natural form. 

ZIPping a file results in a new, smaller file which is 
suffixed with '_zip' For example, the TurboQuill 
version of Quill (60614 bytes) would become 
Quillzip (39833 bytes). The command line syntax for 
using the QDOS version of ZIP is: 

EXEC _W win! ZIP; "zipname winlfileone" 
where 'win 1 ' is where the ZIP program is located (the 
location is optional), 'zipname' is the name that you want 
for the ZIPped file, and 'winl fileone' is the location and 
actual name of the file you want to ZIP 
You should note that, as with UNZIP, the command and 
argument(s) are separated by a semi-colon, and, the 
arguments are enclosed within quote marks. 
It has been said that sometimes a little knowledge is a 
dangerous thing; and, this was the case with my attempts to 
implement ZIP and write the ZipaDee_bas program, 
Being familiar with the DOS versions of the ZIP program I 
observed that the QDOS version lacked the '-a' switch for 
amending existing ZIP files. 

This seemed like a great omission that would require 
including all the filenames to be incorporated into a ZIP 
file at the time of the creation of the ZIP file The 



command line syntax would be: 

EXEC_W win l._Z IP; " z ipnarae 

winl_f ileone flp2_filetwo" 

where 'flp2_filetwo' might be the device and location of the 
second file, and so on. 

Subsequent to writing the current version of the program I 
belatedly ascertained that the '-a' switch has been renamed '- 
u' (i.e., update), and, the command line syntax is: 

EXEC_W winl_ZIP;"-u zipname winl_fileone" 
My ignorance prevented the program from resulting in a 
more cumbersome implementation for the user, so, all's 
well that ends well. 

Select Hew ice 

There are several device options. Pressing 'W will select 
'winlj; pressing 'X' will select 'win2 _'; pressing 'F' will 
select 'Apr, pressing 'G' will select 'flp2_'; and, so on. Use 
the 'other' option if you want to key in a device name (e.g., 
iomlj) 

ff you are looking at the menu of filenames and want to 
return to the SELECT DEVICE option, press '0' (zero); 
however, you should note that all pre-selected filenames 
will be lost. 

Change Device 

To expedite mufti- source ZIPping, you can change to 
different devices by using a "CONTROL SHIFT 
single letter" key combination. The following are 
supported (you can modify the LISTing if you choose). 

CTRL SHIFT F == flpl_ 

CTRL SHIFT M == mdvl_ 

CTRL SHIFT N == ndkl_ 

CTRL SHIFT 0 == roml_ 

CTRL SHIFT R == raml_ 

CTRL SHIFT W == winl_ 
To move from flpl_ to flp2_ (for example), simply use the 
right_arrow key. 

CONTROL LEFT key to move to the device designated 
near the right_arrow near the bottom of the screen if the 
device type differs from the currently accessed device. 
Press '0' (zero) to access the SELECT DEVICE menu if 
you want to start over. 

Zipping A File 

Presuming that the program has been properly typed in, if 



ZXir QLive Alive! 



12 



Autumn 1998 



you want to ZIP a program, you simply have to press the 
key which corresponds to the alphanumeric character in the 
brackets '{ }' to the left of the filename The file will be 
ZIPped and stored on your default DATAUSE device 
(usually FLP2 _) 

If you have more than 1 Meg of memory then you can 
employ "DATA USE RAM2_", but, don't forget to 
move the(se) ZIPped file(s) to a disk before quitting! 
ABOUT THE LLISTing 

ZipaDee is a modification of the DooDahbas program 
LLISTing, and some meaningless statements may still be 
included. 

You should note the REMarked statements (Line 140 & 
150). You can UN-REMark these if you have more than 1 
Meg of memory 

If you do not have a hard drive, then substitute "winl_" 
with "flpl_" or any other appropriate device in Line 150 & 
Line 160 and (especially) Line 1010. 

There are some changes to the general program, but if 
you already have a. functional copy of DooDah bas, 
then you can just change the "Main" DEFine(d) 
PROCedure to the following (your line numbers may 
differ): 

8nn LET Zipf ile$=Z$ (k+1 ) 
8nn filename$=t$&W$&"__"&Z$ (k+1) 
8nn DoWhat$=Zipfile$&" "&filename$ 
8nn CLS#2 

8nn IF k<c THEN EXEC_W 
win 1 _z ip ; DoWhat $ 

As you can see, this will only provide limited functionality 
by allowing only one file to be ZIPped at a time 
If you want the capability to ZIP more than one file, then 
you will probably want to input the LISTing below (also 
based originally on the DooDah bas program, so you can 
save some keyboard entry). 

Originally, a more complex structure for multiple ZIPs 
was being written, but in a moment of inspiration, I 
realized that it might be possible to simply extend the 
DoWhatS string; and, that is the method used. 
The files to be included can be verified prior to ZIPping by 
pressing the V key. The files you have selected will appear 
in the upper part of the screen. 

You will be asked for a ZIP file name after you have 
selected all the files you want to ZIP. 

The following listing provides an active menu of 57 
filenames (three columns x 19 files). If the files 
which you want to ZIP are not visible in the menu or 
contained within a sub-directory, then you will want to 
transfer the files to another source medium (e.g., rami , if 
you have "extra" memory), or, modify the QLUTter bas 
program to contain the MANE & MAIN procedures instead 
of one of QLUTter's current utility PROCedures. 

odnd damfudUtG^ (JLa "Xjjau .... 

4 0 REMark 

************************************** 



ZIP-A-DEE 1.105b 
by Al Feng 



50 REMark * 
60 REMark * 

7 0 REMark * A ZIP FRONT END 

8 0 REMark DATA_USE RAM1_: ******** 
as ZipaDee_bas ******* 

90 REMark COPY winl zip TO ram8 zip 



SAVE 



100F$="_FLIST imp": t$="win": S$="win": W$="l"; 
Do$=" " 

110 pn=0: POKE 163890,0: MODE 0 

120 WINDOW#2,512,256,0,0: PAPER#2,7: 

BORDER# 2,1,7: INK# 2,0: CLS # 2 : 

WINDOW#0 ,413,10,50,241: PAPER#0 , 0 : 

INK#0, 7 : WINDOW462, 250, 25, 3: 

OPEN#3, scr_458x200a27x48: u$=" ZipaDee 

1.105 ": AT#2,21,4: 

130 PRINT#2,u$;" by Al Feng "\TO 4;" @ 

1998 PLATYPUS Software ": PAUSE 30 

140 PAPER 7: BORDER 1,7: CLS: CL: lne : 

AT 0,7: PAPER 2: INK 7: PRINT" 

SELECT_DEVICE ": cj 

150 DEFine PROCedure CLSe: BLOCK 

458,225,0,10,0: END DEFine 

160 DEFine PROCedure CLSd: 

BLOCK#2, 330, 10, 83, 240, 0: END DEFine 

170 DEFine PROCedure CLSe: BLOCK 

458, 190, 0, 45, pn: END DEFine 

18 0 DEFine PROCedure CLSf: BLOCK 

458,30,0,10,0: END DEFine 

190 DEFine PROCedure Press: CLS#0: 

INK#2,5: AT#2,24,30: PRINT#2 , "Press 

Any_Key to Continue" : END DEFine 

200 DEFine PROCedure sx : DIM Z$(60,32): 

DELETE t$&W$&F$ 

210 OPEN_NEW # 6 , t $ & W$ & F$ 

220 DIR#6, t$&W$&"_" : CLOSE #6 

230 OPEN_IN#7,t$&W$&F$: FOR c=0 TO 60 

2.40 IF EOF (#7) THEN EXIT c 

250 INPUT#7, Z$ (c) : END FOR c: CLOSE #7 : 

c=c-l: END DEFine 

2 60 DEFine PROCedure sw: IF W$<=8 THEN 
g$=W$-l: IF W$>=1 THEN h$=g$+2 
27 0 IF g$=0 AND t$="flp" THEN LET 
tl$="ram": ELSE tl$="flp": END IF : 
gl$=l 

280 IF g$>0 THEN tl$=t$: gl$=W$-l: END 
IF 

290 END DEFine 

300 DEFine PROCedure Rx: CLSf: INK#3,7: 

PAPER#3,0: AT 2,3: PRINT 

t $ / W$ ; "_" ; : INK 7 : PRINT Z $ ( 0 ) : Rx 1 : END 

DEFine 

310 DEFine PROCedure Rxl : FOR a=0 TO 18 

32 0 IF a<l THEN a=a+a 

330 FOR n=l+ a +a: AT#3,a,0: 

PRINT#3 , " { " ,CHR$(n+a+48); " } " ;Z$(n+a+ 1 ) 

340 FOR n=2+a+a: AT#3,a,26: 

PRINT #3, "{";CHR$ (n+a+48) ;"} ";Z$ (n+a+1) 

350 FOR n=3+a+a: AT#3,a,52: 

PRINT # 3 , " { " ; CHR$ ( n+ a +■ 4 8 ) ; ,f } " ; Z $ ( n+ a + 1 } 

360 NEXT a: END FOR a: rx2 : END DEFine 

370 DEFine PROCedure rx2 

380 STRIP#2,0: INK#2,7 

390 BLOCK 2,13,18,235,2: BLOCK 

2,12,436,236,2: BLOCK 458,1,0,235,2 

400 BLOCK 18,12,0,2.36,0 

410 BLOCK 20,12,438,236,0 

420 BLOCK 416,12,20,236,0 

430 AT#2,2.4,5: INK#2,7: 

PRINT#2,CHR$ (188) ; " ": AT#2,24,78: 



ZXir QLive Alive 



13 



Autumn 1998 



PRINT#2,CHR$ (18 9) ;" " 
4 40 AT#2,24,8: INK#2,5: 
PRINT#2,tl$&gl$; "_"TO 71;t$&h$;"_" 

450 END DEFine 

4 60 DEFine PROCedure Uu: sx: pn=0: CLSe: 

Uv: END DEFine 

470 DEFine PROCedure Uv: sw: Rx: k3: pk: 
END DEFine 

4 80 DEFine PROCedure Uw: wx: k3 : pk: END 
DEFine 

490 DEFine PROCedure pk: k=k-48 
500 IF k=-21 THEN CLS#2: nd 
510 IF k<-l AND k<>-14 THEN Uw 
520 IF k=-14 THEN Uw 
530 IF k=68 THEN Uv 

540 IF k=144 THEN IF W$>1 THEN W$=W$-1: 
Uu: ELSE : iX: Uw 

550 IF k=118 THEN t$="flp": a$=l : sx: 
MAIN 

560 IF k=125 THEN t$="mdv" : a$=l: sx: 
MAIN 

570 IF k=126 THEM t$="ndk" : a$=l: sx: 
MAIN 

580 IF k=127 THEN t$="rom": a$=l: sx: 

MAIN 

590 IF k=130 THEN t$="ram" : a$=l: sx: 
MAIN 

600 IF k=135 THEN t$="win" : a$=l : sx: 
MAIN 

610 IF k=146 AND t$="ram" THEN t$="flp" : 

LET a$=l: Uu 

620 IF k=146 AND t$="win" THEN t$="flp": 
LET a$=l: Uu 

630 IF k=146 AND t.$="flp" THEN t$="ram": 
LET a$=l: Uq 

640 IF k=152 THEN IF W$<2 THEN W$=W$+1: 

Uu: ELSE : iX: Uw 

650 IF k=156 THEN W$=W$+1: Uu 

660 IF k=79 THEN CLS#2: l.ne : t.re=3: WCh 

670 IF k=0 THEN GO TO 14 0 

680 IF k>=58 THEN Uw 

690 END DEFine 

700 DEFine PROCedure wx: STRIP#2,2: 
INK#2,7: AT#2,24,29: PRINT#2 / " 

ERROR " TO 49;" ERROR " : AT # 2 , 2 4 , 3 6 : 
STRIP#2, 0:PRINT#2, '* WRONG KEY"; : 
INK#2 / 5: PRINT#2 / "!": STRIP#2, 7 : INK#2, 0 : 
B5: CLSd: B5: END DEFine 
710 DEFine PROCedure iX: AT#2 / 24 / 35: 
PRINT#2, "invalid drive": B5: PAUSE 10: 
END DEFine 

720 DEFine PROCedure k3: REPeat key 
730 k=CODE ( INKEY$ ) : IF k>8 THEN EXIT key 
74 0 END REPeat key: END DEFine 
7 50 DEFine PROCedure yeano 

7 60 REPeat ysn 
77 0 c$=INKEY$ 

780 IF c$=CHR$(27) OR c$=="n" THEN 
ok=0:EXIT ysn 

790 IF c$=CHR$(10) OR c$=="y" THEN 
ok=l:EXIT ysn 

8 00 END REPeat ysn: END DEFine 
810 : 



820 DEFine PROCedure MANE 

830 Do$=" " 

840 MAIN 

850 END DEFine 

860 DEFine PROCedure MAIN 

870 BORDER 1,2: BLOCK 458,12,0,0,2: STRIP 

2: AT 0,37: INK 7: PRINT "zip" 

880 CLSc: STRIP 0: INK 2: AT 2,5: 

PRINT" ZIP ": sw: cr=0: Rx 

890 k3: pk 

900 IF k=-l THEN CLSf: INK 5: AT 1,0: 

PRINT Do$: Press: PAUSE: Rx: GO TO 950 

910 LET Zipfile$=Z$ (k+1) 

920 fil.enarae$=t$&W$&"_"&Z$ (k+1) 

930 AT 2,3: INK 7 : PRINT" ZIP " ; : INK 

5: PRINT filename$ ;: INK 2: PRINT " 

(y/n)" 

940 yeano: IF ok THEN Do$=Do$&" 

"&filename$:ELSE GO TO 950 

950 CLSf: AT 2,3: INK 7: PRINT" ZIP ";: 

INK 5: PRINT "another" ;: INK 2: PRINT " 

(v/n)" 

960 yeano: INK 2: IF ok THEN Bl : Rx: 
STRIP#2,7: CLSd: rx2 : GO TO 890: ELSE GO 
TO 970: END IF 

97 0 CLSf: AT 2,3: INK 5: INPUT "ZIP file 
name: ";name$ 

980 IF name$="" THEN GO TO 97 0 
990 CLS#2 

1000 DoWhat$=name$&" "&Do$ 

1010 EXEC_W winl_zip;DoWhat$ 

1020 CLS#2: BORDER#2 ,1,7: wx: MAIN: END 

DEFine 

1030 : 

1040 DEFine PROCedure Bl: BEEP 100,10: 
END DEFine 

1050 DEFine PROCedure B2 : BEEP 200,20: 
END DEFine 

10 60 DEFine PROCedure B3: BEEP 900,20: 
END DEFi.De 

1070 DEFine PROCedure B4 : BEEP 900,40: 
END DEFine 

1080 DEFine PROCedure B5: B3: PAUSE 5: 

B4: END DEFine 

1090 DEFine PROCedure Ine: 

BLOCK#2, 458, 1,24,2, 0: 

BLOCK 4 58,1,0,10,0: END DEFine 

1100 DEFine PROCedure nd: PAPER 7: Ine: 

B2: tre=l: WCh: END DEFine 

1110 DEFine PROCedure CL: BLOCK 

450,2.20, 0, 11,7: PAPER 7: INK 2: AT 

0,64: PRINT CHR$(188)& ? shift TAB ': AT 

0,0: PRINT" TAB "&CHR$ (189) : INK 0:AT 

0,7: PRINT " S E LE C T_DE V ICE ZIP "TO 

57;" EXIT " : PAPER 2: INK 7: END DEFine 

1120 DEFine PROCedure K4 : PAPER 7: 

REPeat key 

1130 i ke=CODE ( INKEY$ ) 

1140 IF ike=9 OR ike=32 OR ike=252 OR 
ike=253 OR ike>4 7 AND ike<58 THEN B3: 
EXIT key 

1150 IF ike>=58 AND ike<252 THEN B4 : K4 
1160 END REPeat key: END DEFine 



ZXir QLive Alive 



14 



Autumn 1998 



1170 DEFine PROCedure Pick 

1180 IF ike=253 THEN B4 : PrvW 

1190 IF ike=9 THEN B3: NxtW 

1200 IF ike=252 THEN B4 : B5: GO TO 1530 

1210 END DEFine 

122 0 DEFine PROCedure NxtW 

1230 tre=tre+l: IF tre=3 THEN tre=0 

124 0 WCh: END DEFine 

1250 DEFine PROCedure PrvW 

1260 tre=tre-l: IF tre<0 THEN tre=2 

127 0 WCh: END DEFine 

1280 DEFine PROCedure WCh: lne: CL 

1290 IF tre=0 THEN AT 0,7: PRINT" 

SELECT_DEVICE ": K4 : Pick: cj 

1300 IF tre=l THEN AT 0,22: PRINT" ZIP 

": K4: Pick: CDS: MAIN 

1310 IF tre=2 THEN AT 0,57: PRINT" EXIT 
": K4: Pick: GO TO 1530 
1320 END DEFine 

1330 DEFine PROCedure cj : pn=7 : CLSe: 
BLOCK 90,100,42,11,0: BLOCK 
88, 99, 43, 11, 7 

134 0 PAPER 0: INK 7: AT 10,7: S$= 



1380 IF s=253 THEN B4: BLOCK 
90,112,42,11,7: tre=3: WCh 



1390 IF 
W$="l" 
1400 IF 
W$="2" 
1410 IF 
W$="l" 
1420 IF 
W$="2" 
1430 IF 
W$="l n 



s=77 OR s=109 THEN t$="mdv" : 

GO TO 148 0 
s=78 OR s=110 THEN t$="mdv" : 

GO TO 1.480 
s=70 OR s=102 THEN t$="flp": 

GO TO 1480 
s=71 OR s=103 THEN t$="flp": 

GO TO 14 8 0 
s=82 OR s=114 THEN t$="ram" : 



50 TO 1480 



-"ram" 



:"wi.n" 



:"win" 



:$: 



PRINT" [ 



INK 5: PRINT S$&W$;: INK 



7: PRINT "_mode ] ": AT 11,7: PAPER 2: 
PRINT u$: PAPER 7 
1350 INK 0: BEEP 100,29: AT 2,9: 
PRINT' "W" = winl_' : AT 4,9: PRINT' "F" = 
flpl ': AT 6,9: PRINT '"R" = rami ': AT 
8,9: PRINT 1 "O" = other' 
13 60 s=CODE ( INKE Y$ ( - 1 ) ) 
1370 IF s=9 THEN B3: BLOCK 
90,112,42,11,7: tre=l : WCh 







1440 IF s=84 OR s=116 THEN t$= 
W$="2" : GO TO 1480 
1450 IF s=87 OR s=119 THEN t$= 
W$="l" : GO TO 1480 
1460 IF s=88 OR s=120 THEN t$= 
W$="2" : GO TO 148 0 

1470 IF s=79 OR s=lll THEN WINDOW#0,90, 
30, 69, 84: PAPER# 0,7: INK# 0,2: other 
1480 sx: B5: MANE : END DEFine 
1490 DEFine PROCedure other : INK#0, 0 : 
AT#0,0,7: PRINT #0, " "&CHRS (188) &"_ 
INK#0,2: AT#0,0,8: INPUT#0,t.$;: IF 
LEN(t.$}<>3 THEN GO TO 1480: END IF 
1500 INK#0,5: AT#0,0,11: PRINT#0,"_": 
INK#0,2: AT#0,0,11: 
INPUT#0,W$: IF CODE(W$)>56 OR 
CODE(W$)<4 9 THEN GO TO 1510: 
WINDOW#0, 413, 10, 50, 241 :END IF 
1510 END DEFine 

1520 CLS#2: PAPER#2,7: INK#2,2: AT#2,24, 
32: PRINT#2,"@ PLATYPUS Software" 




cr dpdate 



by Al Feng 



QLAMBer has recently been updated to reflect known 
changes in QDOS compatible hardware 

Wiaat's New 

To facilitate greater user convenience, the new RomDisq is 
acknowledged as a quick key device in the "other" option 
(NB: it is my understanding that "rom" is the device name 
for the RomDisq, and, this will be corrected if I am advised 
it is different). 

FLP device supported with ' f 
MDV device supported with 'm' 
NDK device supported with T n' 
RAM device supported with 'r' 
ROM device supported with 1 o' 
WIN device supported with 'w T 
Further, the "CONTROL SHIFT" quick_key combination 
pioneered in ZipaDee bas has been incorporated into the 
current version of QL AMBer (2 .205). 

flpl _ device accessible with 'CTRL SHIFT f 
mdvl_ device accessible with 'CTRL SHIFT ni 
ndkl_ device accessible with 'CTRL SHIFT n' 
raml_ device accessible with 'CTRL SHIFT r' 
roml_ device accessible with 'CTRL SHIFT o' 
winl_ device accessible with 'CTRL SHIFT w 1 
Pressing one of these combinations will "return" you to the 



EXEC W screen for the device selected . 

QLAMBer is compatible with SMSQ (QXL), Minerva, 

JS/JSU, QLAY (some limitations exist due to the 

emulation) . If your current version is compatible with what 

you are currently using and the ROM code is different than 

those listed, then QLAMBer should continue to be 

compatible. 

How To Get Your Copy 

If you have e-mail then you can get a FREE upgrade if you 
have previously purchased a copy of QLAMBer, QLUSTer, 
or QLUTter from either EMSoft, UPDATE!, or 
PLATYPUS Software by simply e-mailing me 

aifeng@juno.com 
You will receive a ZIPped file that has been encoded 
for transmission. 

You will need to have the facility to decode the file. 
A UUEncoded file will be sent unless you indicate 
otherwise (i.e., MIME or BinHex). 

To receive an upgrade by disk, please send $2.00 and 
indicate disk size to: Al Feng 

914 Rio Vista Circle SW 
Albuquerque, NM 87105 



ZXir QLive Alive 



15 



Autumn 1998 



QLRTter 1 . 1 0S 



by A I Feng 



QLATter is a freeware utility intended for use with 
Jan Venema's QLAY emulator; but, it can be used with a 
"regular" QL or any other QDOS compatible, too 
The source code for the program has been corrected and 
updated so that the COPY function works, and the 
FORMAT® function has been replaced with a M@KJDIR 
(faux/mock sub-DIRectory) option. 

At the present time, Hard-COPY remains non- 
functional due to limitations in the QL AY emulation; but, it 
will work on other QDOS compatibles 
QLATter supports easy sub-DIRectory access and is 
Minerva and SMSQ compatible. 
TK2 _EXTensions are not required. 

SELECT DEVICE '0' 
While QLATter's ' SELECT DEVICE' option does not have 
"mdvQ" as a ready option, microdrives users can access 
the two devices on their QL via 'other' 
If you select 'other', then you can simply press 'm' and then 
the <ENTER> key, followed by either T or '2* and then the 
<ENTER> key, again 

Otherwise, simply move the green bar up or down 
using either the up arrow or down arrow key, or by 
pressing the first letter of the device name 
Change the device number by using the left_arrow or 
right arrow key or by pressing a numeric key whose value 
is between T & '8*. 



M@K_DTR [F4] 
M@K_D1R' allows you to create a fake/mock sub- 
directory name ("fake_name ->) which will then allow you 
to look at appropriately prefixed files (i.e., with the same 
"name") as if they were in a MAKEJDIR created sub- 
directory. 

If you have selected the wrong device, then input 
MORE than ten 10) characters in the name to reset or 
simply press the (esc)ape key to exit. 

The 'M@K_DIR' facility traps for duplicate filenames 
on the same medium. 

Getting A Copy Of QLATter 
QLATter is really free if you send an e-mail message to me 
at: alfeng@juno com 

I will send you a UUENCODED ZIP file which you must 
be capable of UUDECODing and UNZIPping at your end 
You will also receive a QLATter txt file 

If you do not have e-mail, then please send $1.00 in 
the US or four (4) IRCs elsewhere to cover the cost of the 
disk and postage. Please specify disk size. 
You can contact me at 

Al Feng 
914 Rio Vista Circle SW 
Albuquerque, NM 87105 

Happy Trails, 

And Computing, To You ... 



Hcuu Id IH SBDsCd di 



afifri i[T| 
l Sffl n H H if m ffl 



Les Cottrell 



PART 4 - DECRYPTERS 

By this point, you should be familiar with headerless 
loaders, which take up the bulk of most protection 
systems these days However, there is one other 
important aspect of protection that you need to know 
about if you are to crack the more complex protection 
systems. It's encryption. 

Encryption works like a secret code You start off 
with something unintelligible, then you use the "secret 
rules" to change it into something that makes sense So, 
IBDLFST doesn't make much sense, but if you take the 
previous letter in the alphabet each time, you get 
HACKERS, which makes perfect sense. Encryption 
works in roughly the same way. We've already seen that 
a loading system occupies a small area of memory. An 
encrypted loading system will appear as a block of code 
which makes absolutely no sense whatsoever There will 
also be a short program which changes all this nonsense 
into workable code so the loading system can be run. 
Some really tough loading systems, have more than one 
decrypter, such as the Alkatrazz loading system which 
has 250 of the damn things; in practice I've got through 
about 25 before going mad and hacking something else 
(don't worry, there's another way of hacking them which 
I'll tell you about later.) 

To make it easier for you to understand decryption, 
its best to have a look at a real loading system As an 
example, I've chosen Impossaball, which was on the 
YS#75 covertape. Load up STK at address 50000 (it's a 



safe address), and see what the BASIC has to say for 
itselfbvBLOADingit 

10 CLEAR 64530 LOAD CODE RANDOMIZE USR 

64531 

20 LOAD CODE 16384 

21 FOR i=l TO 40 STEP - RANDOMIZE USR 50000 
Fair enough - so enter CLEAR 64530:LOAD 

CODE and start the tape The first code block loads in, 
and then - it crashes! What's going on? Don't worry, you 
have just fallen victim to the first type of encryption - 
BASIC encryption. 

In BASIC, any numerical constant (techno-twaddle 
for "number") between 0 and 65,535 is stored in the 
memory as follows. First, there is the number in it's 
ASCII form, which takes between 1 and 5 bytes So, the 
number 1234 will appear as #30,#31#,#32,#33 here. 
Then, come the numbers #0D,#00 and 00 (this is always 
the case) Then, there is the number stored in it's two 
byte form (as in machine code). What happens it that the 
computer prints the ASCII form (which is what you get 
when you LIST a program), but uses the two-byte form 
in calculations and expressions. The upshot of all this is 
that what you see isn't always what you get! As an 
example, type in this: 
1 PRINT l 

Now type POKE 23760,50 (which changes the 
ASCH value of the number 1 from "1" to "2") Now if 
you LIST the program, you will see 1 PRINT 2, but if 



ZXir QLive Alive! 



16 



Autumn 1998 



you RUN the program, the computer will print the 
number 1 instead! 

Needless to say, protection systems use the same 
idea. Sometimes, the numbers listed are obviously fake 
(if you list a program and you get something like 0 
CLEAR 0: RANDOMIZE USR 0 it's obviously got 
encrypted BASIC), but some programs, like the 
Impossaball are not obvious at all until you try executing 
what you see. 

There was a program called *List printed ages ago 
in YS, but if you haven't got that, I've reprinted it here. 
So type it in, SAVE it to tape, RUN it and reload the 
Impossaball BASIC loader, 
loading LINE 10LEN81 

10 CLEAR 255 99: LOAD CODE : RANDOMIZE 
USR 64512 

20 LOAD CODE 16384 

21 FOR i=l TO 40 STEP ????.... 

Now that's what you really get! Type CLEAR 
25 599 :LQ AD CODE and load in the first block of 
code. When that's done, load up your disassembler, and 
disassemble address 64512 (FC00 hex) to have a look at 
the decrypter 

FC00 01 99 02 LD BC,#0299 
FC03 21 13 FC LD HL,#FC13 
FC06 11 14 FC LD DE,#FC14 

This part of the progr am sets up all the initial values for 
the Decrypters in some of the registers 

FC09 LA LD A, (DE) 

We've come across brackets before, but briefly 
what happens here is that the contents of the address with 
the value of the DE register (which starts of as #FC14) 
are put into the A register. So now the A register could 
contain any byte. 

FC0A AE XOR (HL) 

We haven't seen XOR before, so I'll explain what 
it does. It is in technical terms a Boolean Operation. You 
may have seen XOR gates if you studied (or are 
studying!) Physics, Electronics or Computer Science at 
school. An XOR gate has two inputs, which can each 
either be 0 or I, and one output, which can be either 0 or 
1 as well. If the two inputs are the same (0 and 0, or 1 
and 1), the output is 0, otherwise it is 1. In machine code, 
you XOR the A register with a number or contents of a 
register, and what happens is that each bit in the A 
register is XORed with the same bit in the number or 
register contents, and the result is stored in the A 
register. If you're confused, look at the example below. 

Contents of the A register 00100101 

Number to be XORed with 0 1 0 1 00 1 1 

Result 01110110 
(Notice that all the numbers are in binary - see your 
Spectrum manual for more information about this). 

if you still don't understand, just remember that an 
XOR will change the contents of the A register That's 
all you need to remember for now. 
Continuing the disassembly... 

FC0B 77 LD (HL) ,A 

This puts the value of A (which has just been 
changed) into the bytes at the address with the value of 
the HL register (which starts off as #FC13). 

So, the routine has basically taken a byte out of a 
memory location, changed it a bit, and put the altered 



value back again. This is decryption in its most obvious 
form - the changed values make up a working machine 
code program 

FC0C 23 INC HL 
FC0D 13 INC DE 
FC0E 0B DEC BC 

I don't think I've mentioned INC before, but it's 
basically the opposite of DEC in that it increases the 
value in whatever register So the values in the HL and 
DE registers are incremented, and the value in the BC 
register is decremented. 

FC0F 7 8 LD A, B 

FC10 Bl OR C 

FC11 20 F6 JR NZ,#FC09 

This is a standard piece of code, and it essentially 
means "If BC isn't 0, then jump to #FC09". In other 
words, another byte will be decrypted until the value of 
BC is 0 (which happens when everything has been 
decrypted), and the decrypter ends. 
Continuing the disassembly . 

FC13 5C LD E,H 

FC14 9F SBC A, A 

FC15 A5 AND L 

FC16 5B LD E, E 

FC17 13 INC DE 

FC18 5B LD E,E 

Hang on - this code doesn't make sense! It has no 
relation to the code above, and the instruction LD E,E is 
pointless anyway. Well, you'll remember that the initial 
value of decryption is #FC13, which means that all the 
code from there onwards has to be decrypted So we'll 
have to crack the decrypter to go any further. 

Sometimes, it is possible to put an EI/RET 
instruction directly after the decrypter, but this is not 
possible here, as you will see So instead, we'll have to 
move the decrypter somewhere else in memory, and put 
the EI/RET on the end (in actual fact we don't need the 
EI because there is no DI command in the decrypter) 
This is easily done by using the LDIR command. Type in 
the following program 

1 FOR N=23296 TO 2 3310: INPUT A: POKE 
N, A: NEXT N 
Now RUN it and enter the following numbers: 
33, 0, 2 52, 17, 1.2 8, 91,1,1,18,0,237, 17 6,54,2 01 
,201 

The program you have just typed in is this 

LD HL,FC00 
LD DE,5B80 
LD BC, 0012 
LDIR 

LD (HL),C9 
RET 

Now RANDOMIZE USR 23296 and the decrypter 
will be copied to 5B80 and a RET will be stuck on the 
end. Just RANDOMIZE USR 23424 (5B80 in decimal) 
to run the decrypter When the OK message comes up, 
restart the disassembler and look at FC13 again: 

FC13 C3 3A FEJP #FE3A 
This jumps to #FE3 A, to start the loading. 
FE3A F3 DI 

FE3B 21 00 58 LD HL,#5800 

FE3E 11 01 58 LD DE,#5801 

FE41 01 FF 02 LD BC,#02FF 

FE44 36 00 LDIR 

As you already know, this makes the screen black. 



ZXir QLive Alive! 



17 



Autumn 1998 



FE48 CD 81 FE CALL #FE81 
FE4B CD 00 80 CALL #8000 

If you look at the code at #FE81, you'll see it's a 
headerless loader The routine at #8000 prints the loading 
screen 

FE4E CD 81 FE CALL #FE81 

FE51 CD 00 64 CALL #6400 
This loads another block (the main game), and prints 
another screen (the border for the game). 

FE54 F3 DI 

FE55 31 FF FFLD SP,#FFFF 
This disables interrupts and changes the stack pointer, so 
we'll have to change that in the final hack 

FE58 21 00 6DLD HL,#6000 

FE5B 11 00 5BLD DE,#5BQ0 

FE5E 01 00 8FLD BC,#8F00 

FE61 ED BO LDIR 
This is another LDIR command, but if you know 
how the Spectrum's memory is organised, you will see 
that the BASIC system variables are overwritten, which 
means we can't return to BASIC when the game has 
loaded. Fortunately, there's a short routine to get round 
this, which I'll explain in a mo. 

FE63 21 71 FELD HL,#FE71 

FE66 1.1 00 FOLD DE,#F000 

FE69 01 10 00 LD BC,#0010 

FE6C ED B0 LDIR 

FE6E C3 00 F0 JP F000 

This moves the code from FE71 to F000, and jumps to 
F000. Obviously, then, the code at FE71 is important. 

FE71 21 00 FC LD HL,#FC0 0 
FE74 11 01 FC LD DE,#FC01 
FE77 01 FF 01 LD BC,#01FF 
FE7A 36 0 0 LD (HL) , 0 

FE7C ED B0 LDIR 
FE7E C3 0 0 8 0 JP #8000 

This routine wipes out all the memory from #FC00 
to #FC0 1 , but in actual fact you don't need to do this. 
Then it jumps to #8000, which is the start of the game. 
So, we can put a machine code routine to put a POKE in, 
and then jump to #8000. 

However, we've got to find the POKE first, and 
there's the problem that we can't use BASIC because it 
is overwritten. Luckily, there is a short routine you can 
use which will cause a NEW to a certain address. Put it 
into the above program by typing in the following: 
1 FOR N-65137 TO 65144: INPUT A: POKE 
N, A: NEXT N 
Then RUN it, and enter these numbers in turn: 
243, 175, 1.7, 0, 95, 195, 20.3, 17 

The program you've just typed in is the following: 

DI 

XOR A 

LD DE,#5F00 
JP #11CB 

DI disables interrupts, XOR A loads A with 0 
(think about what would happen if you XORed the value 
of the A register with itself, LD DE,#5F00 means we 
want to NEW up to #5F00 (this value can be changed 
from about #5D00 to #FFFF), and JP #11 CB starts the 
NEW. 

Now RANDOMIZE USR 65082 (#FE3A in 
decimal), and restart the game tape When the computer 
resets, you can load STK into address 24320 to find 
POKEs. 



Phew! And that's about all of that protection 
system cleared up. If you can get your way through that 
lot, I think you're probably ready to have a go at a 
"commercial" protection system. First, though, we'll 
write a complete hack for the game 

10 CLEAR 25599: LOAD CODE 
This is from the BASIC loader, and it loads in the first 
machine code block 

20 FOR N-23296 TO 23310: READ A: POKE 

N, A: NEXT N 

This line POKEs in the machine code program to move 

the decrypter 

30 DATA 33,0,252,17,128,91,1,19,0,237, 
176, 54,201, 201 

And here's the actual machine code itself 

40 RANDOMIZE USR 2 32 96 
This line calls the decrypter and returns to BASIC 

40 FOR N=65137 TO 65143: READ A: POKE 
N, A: NEXT N 

This line POKEs in our hacking program 

50 DATA 175, 50, ??,??, 195, 0,12 8 

And here's the hacking program, which loads ???? with 
0 (which is the infinite lives POKE), and jumps to 
#8000. 

60 RANDOMIZE USR 65082 

This starts the whole loading system off, with the 
POKE firmly in place 

And that's about it. A bit of a long piece of work, 

but it was worth it! 

PART 5 - Advanced Hacking Methods 
Remember in Part 2, when I said there were other ways 
of hacking, apart from forwards and backwards tracing? 
Well, you can find them here But you need a Multiface 
to be able to use them The two we're interested with 
here are what I call a stack trace and an interrupt trace. 

STACK TRACE 

We've already come across the stack as a means of 
storing numbers. What you haven't come across yet is 
how the stack is used Well, in a CALL to a subroutine, 
what actually happens is that the return address from the 
subroutine (which is the address after the CALL 
instruction) is stored on the stack, and with a RET, the 
top value of the stack is taken off and jumped to 

With a Multiface, the value on the top of the stack 
is the return address to the program, and subsequent 
values refer to return addresses in subroutines. 

To do a stack trace, load and play the game, and 
wait until the "death effect" occurs - this may be a beep, 
a flashing border or something else recognizable. Now 
quickly press the Multiface button during this effect - if 
you're too slow, you won't get the values you're looking 
for (so return to the game and die again). Now, look at 
the value of the stack pointer (your Multiface manual 
will tell you how to do this), and write down all the 
values on top of the stack for the first ten bytes. All 
numbers are stored in the normal reversed two-byte 
form, so if the bytes on the top of the stack were 
#00,#80,#80,#70,#90,#60, the values would be 
#8000,#7080 and #6090 Have a look at all of these 
addresses - you should find that some of them are 
addresses right after CALL instructions. 

Now for the hacking bit - go to one of these address 
and write down the two bytes there. Then change them to 



ZXir QLive Alive! 



18 



Autumn 1998 



the magic codes #18 and #FE (this is the machine code 
version of JR -2, which is an endless loop, a bit like 1 
GOTO 1 in BASIC) Restart the game, and hopefully, 
you'll find that the game pauses as soon as you do 
something which would normally result in you losing a 
life' (If not, replace the #18FE with the original two 
bytes, look at another address on the "hit list" and repeat 
the whole procedure). 

Once you've found a target address, try putting a 
RET (#C9) at the start of the subroutine. If this just 
cancels the death effect, but you still "die", activate the 
Genie Disassembler if you have it (or use the NEW 
routine in Part 4 at any address, then load in STK or 
Devpac somewhere far away from the area of memory 
you're looking at), and search for CALLs to this routine 
Then so back from this CALL until you find a RET or a 
JP, and search for the address of the instruction after this 
(if nothing comes up, search for one more than this, then 
two more etc.) You will hopefully either see one of 
these: 

jp z 

JP NZ 
JP C 
JP NC 

(The JP may be a JR or a CALL instead) 

Simply overwrite this instruction with NOPs to get 
immunity or something similar. 

On the other hand, when searching from the C ALL 



address, you may find a JP Z or JP NZ, etc. Change this 
to an unconditional JP to get immunity. 

INTERRUPT TRACE 
This involves looking at the interrupt routine in the 
game. Since the whole routine must be executed in 
1/S0th of a second, the routines are usually quite short, 
especially if there is a LDJR or something similar Most 
of the time you'll find infinite time in this routine 
(because interrupts work in real time, so its an ideal place 
to put a time routine), and you need a Multiface to find 

Load the game and start playing as normal. Then 
activate the Multiface, and have a look at the I register . If 
the value is #3F, there are no special interrupts, so forget 
about an interrupt trace altogether (but you can use a 
stack trace which will make the clock loop round to 99 or 
whatever when it reaches 0). If it is between #80 and #FF 
(and if it's not in that range and not #3F you've probably 
crashed the computer!), go to the address #100 time that 
of the value in the I register (so if the value of I is #F0, 
look at #F000). You will see an area of memory filled 
with the same number Go to this address (if this area of 
memory is filled with #FE, go to #FEFE etc.) There will 
either be a jump to the interrupts routine, or the interrupts 
routine itself Have a look at the routine, and somewhere 
you will see the commands to decrease the timer - just 
remove the DEC instruction to get infinite time. 



RMG 

Inventory 



5 TS 1016 16K RAM Pak (1000) 

2 Magic Bridge- 1 6K RAM Packs 

4 MODEM-Byte-Back Spectraterm V 1 . 3 (2068) 

4 E-Z Key-Upload 2000 (2068) 

4 Timex-Circuit Board Scramble (2068) 

5 Timex-Crazybugs (2068-T) 
1 Wilcox-Tarot (2068) 

1 Wilcox- Yacht (2068, S/W) 

14 Keytops-Cricket House (2068, HAY) 

10 Keyboard-E Z Key Interface Kit (1000, 2068) 

1 Printer-TS2040 Complete (Used) 

94 Timex-Spelling I (2068-T, S/W) 

8 Timex-Crazybugs (2068-T, S/W) 

7 Timex-States & Capitals (2068-T, S/W) 

6 Book-Sams Beginner/Intermediate Guide 
6 Book- Sams Intermediate/Advanced Guide 

10 Book-Computer Interfacing In Science (1000/2068) 

14 Book-T/S 2068 Basics & Beyond (S/W, 2068) 

6 Computer-TS 1000 (H/W) 

4 Keytops-Cricket House (1000) (H/W) 

1 Compusa-Keyboard Bleeper Kit ( 1 000, H/W) 

1 Keyboard-Ti Surplus (1000, 1500, H/W) 

13 Book-The Ins & Outs Of TS1000 (S/W, 1000(1500) 
20 Book-TS 1000 Owners Manual (S/W) 
46 Mindware-Gulp(1000, S/W) 

2 Pad-TS 1000 Computer/RAM Desk Pad (H/W) 
52 Softsync- Alien Invasion (1000, S/W) 



52 Softsync-Red Alert! (1000, S/W) 
49 Softsync-2K Games (1000, 1500, S/W) 
7 Timex-Budgeter ( 1 000, S/W) 

24 Timex-The Carpooler (1000, S/W) 
12 Timex-The Challenger I (1000, S/W) 

27 Timex-ChessUOOO, S/W) 
16 Timex-College Cost Analyzer (1000, S/W) 

I Timex-Gambler ( 1 000, S/W) 

25 Timex-Grimms Fairy Trails (1000, S/W) 
6 Timex-Heating System Analyzer (1000, S/W) 

I I Timex-Ira Planner (1 000, S/W) 
32 Timex-Loan Mortgage Amortizer (1000, S/W) 

1 Timex-Mixed Game Bag I ( 1 000, S/W) 
16 Timex-Money Analyzer I (1000, S/W) 

2 Timex-Money Analyzer 2 (1000, S/W) 
1 Timex-Power Pak I (1000, 1500, S/W) 
30 Timex-States & Capitals (1000, S/W) 

28 Timex-Super Math (1000, S/W) 

Jack Boatwright 
87325 Fryrear Rd. 
Bend, OR 97701 
541-389-7353 (H) 
j boatno4 @,outlawnet.com 

For the inventory at J. Shepard, Iowa 
Check with Frank Davis at F WD Computing. 



ZXir QLive Alive! 



19 



Autumn 1998